using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;

namespace cb0tServer
{
    class Whowas
    {
        private static List<WhowasUserItem> ww_items = new List<WhowasUserItem>();

        public static void Clear()
        {
            ww_items.Clear();
        }

        public static void AddItem(UserObject userobj)
        {
            WhowasUserItem ww = new WhowasUserItem();
            ww.name = userobj.name;
            ww.ip = userobj.physical_ip;
            ww.join = userobj.session_spawn_time;
            ww_items.Insert(0, ww);
            if (ww_items.Count > 3000) ww_items.RemoveRange(2499, 500); // trim
            AddRecord(ww);
        }

        public static WhowasUserItem CheckLastSeen(UserObject userobj)
        {
            if (ww_items.Count == 0) return null;

            foreach (WhowasUserItem i in ww_items)
                if (userobj.physical_ip.Equals(i.ip))
                    if (userobj.name == i.name)
                        return null;
                    else
                        return i;

            return null;
        }

        private static void AddRecord(WhowasUserItem item)
        {
            try
            {
                StreamWriter s;

                if (!File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/whowas.dat"))
                {
                    s = File.CreateText(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/whowas.dat");
                }
                else
                {
                    s = File.AppendText(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/whowas.dat");
                }

                s.WriteLine(item.name + "\n" + item.ip.ToString() + "\n" + UnixTimestamp());
                s.Flush();
                s.Close();
            }
            catch { }
        }

        public static bool IsJoinFlooding(UserObject userobj)
        {
            foreach (WhowasUserItem ww in ww_items)
            {
                if (ww.ip.Equals(userobj.physical_ip))
                {
                    if ((ww.join + 15) > userobj.session_spawn_time)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public static WhowasUserItem[] Query(String query)
        {
            if (!File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/whowas.dat")) return null;

            try
            {
                StreamReader s = File.OpenText(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/whowas.dat");
                List<WhowasUserItem> items = new List<WhowasUserItem>();

                while (!s.EndOfStream)
                {
                    String name = s.ReadLine();
                    String ip = s.ReadLine();
                    String time = s.ReadLine();

                    if ((name.ToUpper().IndexOf(query.ToUpper()) > -1) || (ip.StartsWith(query)))
                    {
                        WhowasUserItem ww = new WhowasUserItem();
                        ww.name = name;
                        ww.ip = IPAddress.Parse(ip);
                        ww.timestamp = ReadUnixTimeStamp(time);
                        items.Add(ww);
                    }
                }

                s.Close();

                if (items.Count == 0) return null;

                items.Reverse();

                return TidyResults(items.ToArray());
            }
            catch { }

            return null;
        }

        private static WhowasUserItem[] TidyResults(WhowasUserItem[] input)
        {
            List<WhowasUserItem> tmp = new List<WhowasUserItem>();

            for (int x = 0; x < input.Length; x++)
            {
                WhowasUserItem i = input[x];
                bool exists = false;

                foreach (WhowasUserItem n in tmp)
                {
                    if (n.name == i.name && n.ip.Equals(i.ip))
                    {
                        exists = true;
                    }
                }

                if (!exists) tmp.Add(i);
            }

            if (tmp.Count > 50) tmp.RemoveRange(50, (tmp.Count - 50));

            return tmp.ToArray();
        }

        private static DateTime ReadUnixTimeStamp(String t)
        {
            DateTime tmp = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return tmp.AddSeconds(uint.Parse(t));
        }

        private static uint UnixTimestamp()
        {
            TimeSpan ts = (DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0));
            return (uint)ts.TotalSeconds;
        }
    }

    class WhowasUserItem
    {
        public String name;
        public IPAddress ip;
        public int join;
        public DateTime timestamp = DateTime.Now;
    }
}
